import urllib
import hashlib
from xml.dom.minidom import parseString
from django.conf import settings

if not settings.GAE_CACHE_SECRET_KEY:
    raise Exception('GAE_CACHE_SECRET_KEY not set properly! See http://code.google.com/p/django-gae-cache/')

if not settings.GAE_CACHE_URL:
    raise Exception('GAE_CACHE_URL not set properly! See http://code.google.com/p/django-gae-cache/')

class Api:
    def _genUrl(self, command, *args):
        '''
            Generate URL for GAE admin call:
            GAE_CACHE_URL/_sys/<command>/<auth_hash/params
        '''
        params = [settings.GAE_CACHE_SECRET_KEY] + list(args)  
        hash = hashlib.sha1(''.join(params)).hexdigest()
        url = '%s/_sys/%s/%s%s' % (settings.GAE_CACHE_URL, command, hash, ''.join(list(args)))
        return url
        
    def _parseStatus(self, dom):
        '''
            Parse XML from GAE admin call for 'message' and 'status' values.
            Return them as tuple (status, message).
        '''
        message = dom.getElementsByTagName('message')[0].firstChild.nodeValue
        status = int(dom.getElementsByTagName('status')[0].firstChild.nodeValue)
        return (status, message)
    
    def Invalidate(self, path):
        '''
            Remove given path from GAE cache, if exists.
        '''
        url = self._genUrl('invalidate', path)
        res = urllib.urlopen(url)
        xml = res.read()

        doc = parseString(xml)
        return self._parseStatus(doc)
        
    def InvalidateAll(self):
        '''
            Remove all cached resources from GAE.
        '''
        url = self._genUrl('invalidate-all')
        res = urllib.urlopen(url)
        xml = res.read()

        doc = parseString(xml)
        return self._parseStatus(doc)

    def Refresh(self, path):
        '''
            Re-download given path from source server.
            (Internally calls 'invalidate' and 'get' commands on GAE.
            
            No error checking during invalidation and re-downloading.
            When no exception happen, GAE always returns (0, 'OK')
        '''
        url = self._genUrl('refresh', path)
        res = urllib.urlopen(url)
        xml = res.read()

        doc = parseString(xml)
        return self._parseStatus(doc)
        
    def Stats(self):
        '''
            Returns dict with usage statistics of GAE memcache.
        '''
        url = self._genUrl('stats')
        res = urllib.urlopen(url)
        xml = res.read()
        
        doc = parseString(xml)
        lines = doc.getElementsByTagName('data')[0].childNodes
        
        data = {}
        for line in lines:
            if line.nodeType != 1: continue
            data[str(line.nodeName)] = str(line.firstChild.nodeValue)
        
        return tuple(list(self._parseStatus(doc)) + [data])

if __name__ == '__main__':
    api = Api()
    print api.InvalidateAll()
